package cn.chaos.nio02;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.StandardCharsets;

public class MappedHttp {

    private static final String OUTPUT_FILE = "d:\\MappedHttp.out";
    private static final String LINE_SEP = "\r\n";
    
    private static final String SERVER_ID = "Server: Ronsoft Dummy Server";
    private static final String HTTP_HDR = "HTTP/1.0 200 OK"+ LINE_SEP +
            SERVER_ID + LINE_SEP;
    
    private static final String HTTP_404_HDR = "HTTP/1.0 404 Not Found" + LINE_SEP +
            SERVER_ID + LINE_SEP;
    private static final String MSG_404 = "Could not open file: ";
    
    public static void main(String[] args) throws Exception {
        

        String file = "D:\\Books\\笔记\\React-03.md";
        
        for (int i = 0; i < 5; i++ ) {
            run(file);
            System.out.println("===============================================");
        }
    }
    
    private static void run(String file) {

        
        ByteBuffer header = ByteBuffer.wrap(bytes(HTTP_HDR));
        ByteBuffer dynhdrs = ByteBuffer.allocate(128);
        ByteBuffer[] gather = {header, dynhdrs, null };
        
        String contentType = "unknown/unknown";
        
        long contentLength = -1;
        
        try (   FileInputStream fis = new FileInputStream(file);
                FileChannel fc = fis.getChannel();
                ) {

            MappedByteBuffer filedata = fc.map(MapMode.READ_ONLY, 0, fc.size());
            gather[2] = filedata;
            contentLength = fc.size();
            contentType = URLConnection.guessContentTypeFromName(file);
            System.out.println("contentType = "+ contentType);
        } catch (IOException e) {
            // file could not bbe opened; report problem
            ByteBuffer buff = ByteBuffer.allocate(128);
            String msg = MSG_404 + e + LINE_SEP;
            buff.put(bytes(msg));
            buff.flip();
            // Use the HTTP error response
            gather[0] = ByteBuffer.wrap(bytes(HTTP_404_HDR));
            gather[2] = buff;
            contentLength = msg.length();
            contentType = "text/plain";
        }
        
        StringBuilder sb = new StringBuilder();
        sb.append("Content-Length: ").append(contentLength);
        sb.append(LINE_SEP);
        sb.append("Content-Type: ").append(contentType);
        sb.append(LINE_SEP).append(LINE_SEP);
        dynhdrs.put(bytes(sb.toString()));
        dynhdrs.flip();
        
//        try (
//                FileOutputStream fos = new FileOutputStream(OUTPUT_FILE);
//                FileChannel out = fos.getChannel();
//                    ) {
//            // All the buffers have been prepared; write 'em out
//            while (out.write(gather) > 0) {
//                // Empty body; loop until all buffers are empty
//            }
//        } 
        try (WritableByteChannel bos = Channels.newChannel(System.out );) {
            for (ByteBuffer ba : gather) {
                bos.write(ba);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

 
        System.out.println("output written to "+ OUTPUT_FILE);
    }
    
    private static byte[]  bytes(String input) {
        return (input.getBytes(StandardCharsets.UTF_8)); 
    }
         
}
